const {Controller} = require('egg');
const formidable = require("formidable");
const path = require("path");
const fs = require("fs");
const dayjs = require('dayjs');
const {write: awaitWriteStream} = require("await-stream-ready");
const sendToWormhole = require("stream-wormhole");

class BaseController extends Controller {
    get user() {
        return this.ctx.session.user;
    }

    success(data, msg = 'success') {
        this.ctx.body = {
            code: 0,
            data,
            msg,
            timestamp: Date.now(),
        };
    }

    error(message = 'error') {
        this.ctx.body = {
            code: 'error',
            message,
            timestamp: Date.now(),
        };
    }

    notFound(msg) {
        msg = msg || 'not found';
        this.ctx.throw(404, msg);
    }

    async parse(req) {
        const form = new formidable.IncomingForm();
        return new Promise((resolve, reject) => {
            form.parse(req, (err, fields, files) => {
                resolve({fields, files})
            })
        });
    }

    /**
     * 上传
     * @param category 资源类型
     * @returns {Promise<{files: *[], fields}>}
     */
    async uploadsFile(category = '') {
        const uploadBasePath = 'app/public/uploads'; // 保存文件夹
        const {fields, files} = await this.parse(this.ctx.req); // 文件信息
        const filesRes = [];
        for (const key in files) {
            const file = files[key]; // 文件对象
            let name = this.ctx.helper.getId(); // 获取随机id
            let extname = path.extname(file.originalFilename); // 后缀
            let filename = name + extname;// 新文件名 + 后缀
            let fileInfo = file.toJSON();

            // 创建文件目录
            const dirname = dayjs(Date.now()).format('YYYY/MM/DD');

            function mkdirsSync(dirname) {
                if (fs.existsSync(dirname)) {
                    return true;
                } else {
                    if (mkdirsSync(path.dirname(dirname))) {
                        fs.mkdirSync(dirname);
                        return true;
                    }
                }
            }

            mkdirsSync(path.join(uploadBasePath, category, dirname));

            // 开始读取
            const stream = fs.createReadStream(file.filepath); // 创建读取流
            const target = path.join(this.config.baseDir, uploadBasePath, category, dirname, filename); // 写入路径
            const writeStream = fs.createWriteStream(target); // 创建写入流

            try {
                await awaitWriteStream(stream.pipe(writeStream));
            } catch (err) {
                await sendToWormhole(stream);      //如果出现错误，关闭管道
                throw err;
            }

            // 返回
            let relative_path = path.join('/uploads', category, dirname, filename).replace(/\\/g, '/');// 相对路径
            filesRes.push({
                id: name,
                relative_path: relative_path,
                url: '//' + this.ctx.host + relative_path, // url
                name: name,
                extname: extname,
                originalFilename: fileInfo.originalFilename,  // 原始名字
                size: fileInfo.size,
            });
        }
        return {files: filesRes, fields: fields}
    }

}

module.exports = BaseController;
